home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_1 / grob2eps < prev    next >
Internet Message Format  |  1995-03-31  |  7KB

  1. From comp.sys.handhelds Sun Jan 27 14:05:11 1991
  2. Path: mentor.cc.purdue.edu!noose.ecn.purdue.edu!news.cs.indiana.edu!know!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.rkb
  3. From: akcs.rkb@hpcvbbs.UUCP (Robert Brunner)
  4. Newsgroups: comp.sys.handhelds
  5. Subject: Re: How does one print out a GROB from a PC?
  6. Keywords: GROB, PC printing
  7. Message-ID: <27a26d9b:1803.2comp.sys.handhelds;1@hpcvbbs.UUCP>
  8. Date: 27 Jan 91 06:40:07 GMT
  9. References: <1991Jan24.182436.20395@rick.cs.ubc.ca> <7360058@hpfcso.HP.COM>
  10. Lines: 255
  11.  
  12. I've been meaning to write a program to print out GROBs
  13. for some time.  Reading  the previous posts motivated
  14. me to finally do it.  The program runs on PC-compatibles
  15. under MS-DOS.  Some directions for use can be found in the
  16. comments for the program.  I'm only posting the source code
  17. (written in Turbo C) here, but I will also post the executable
  18. on hpcvbbs in user.programs.  I hope this helps you out.
  19. By the way, this program was written and tested in one Saturday 
  20. afternoon, so it probably includes some bugs (at no extra charge :-))
  21. I'd be interested if others add more options; please get back
  22. to me if you do.
  23.  
  24.              Robert Brunner
  25.                    brunner@uirvld.csl.uiuc.edu
  26.  
  27. /*
  28. /
  29. **  grob2eps.c   version 1.0
  30. **  Robert Brunner
  31. **  1-26-91
  32. **
  33. **  Translate a GROB to a file which can be copied to an Epson
  34. **  printer.  The GROB is sent from the HP-48 to the PC using
  35. **  ASCII mode.  The program is then run with the command:
  36. **
  37. **  C>grob2eps grob_file print_file
  38. **
  39. **  and the results can be printed with the MS-DOS copy command:
  40. **
  41. **  C>copy print_file /b prn
  42. **
  43. **  If either filename is omitted, stdin or stdout are used.
  44. **  Therefore, another way to execute the command is:
  45. **
  46. **  C>grob2eps grob_file >prn
  47. **
  48. **  Bugs:
  49. **  1) Specifying PRN for the print_file sends garbage to the printer
  50. **  2) The program is slow as molasses
  51. **
  52. **  This program was developed for MS-DOS with Turbo C 2.0, although
  53. **  no machine-specific are used, so it may be usable on other
  54. **  systems.
  55. */
  56.  
  57. #include <stdio.h>
  58.  
  59. #define GROBTYP     "GROB"
  60. #define ESC         27
  61.  
  62. main(argc,argv)
  63. int argc;
  64. char *argv[];
  65. {
  66.   FILE *fp_in, *fp_out;
  67.   char ftyp[5], *grobmap;
  68.   unsigned char *bmap;
  69.   int realwidth,width,realheight,height,i;
  70.   long grobsize;
  71.  
  72.   /*
  73.   **  Open files from the command line, or use stdin and stdout
  74.   */
  75.   if (argc>=2) {
  76.     if ((fp_in=fopen(argv[1],"r"))==NULL)  {
  77.       fprintf(stderr,"Can't open grob file\n");
  78.       exit(1);
  79.     }
  80.   } else fp_in=stdin;
  81.   if (argc>=3) {
  82.     if ((fp_out=fopen(argv[2],"wb"))==NULL)  {
  83.       fprintf(stderr,"Can't open print file\n");
  84.       exit(2);
  85.     }
  86.   } else fp_out=stdout;
  87.  
  88.   /*
  89.   **  Find the first occurence of GROB and print out this.
  90.   **  This gets the file pointer past the %%HP junk.
  91.   */
  92.   while (!feof(fp_in)) {
  93.     fscanf(fp_in,"%5s",ftyp);
  94.     if (strcmp(GROBTYP,ftyp)==0)
  95.       break;
  96.   }
  97.   if (feof(fp_in)) {
  98.     fprintf(stderr,"Unexpected eof\n");
  99.     exit(3);
  100.   }
  101.  
  102.   /*
  103.   **  Get the GROB size and the actual grob data
  104.   **  Notice that the width is rounded up to the next multiple
  105.   **  of eight, since this is how they are transmitted.
  106.   **  The real width is saved for printing because the
  107.   **  lines are completed with 1's
  108.   */
  109.   fscanf(fp_in,"%d %d ",&realwidth,&realheight);
  110.   if (realwidth%8==0)
  111.     width=realwidth;
  112.   else width=((realwidth/8)+1)*8;
  113.   if (realheight%8==0)
  114.     height=realheight;
  115.   else height=((realheight/8)+1)*8;
  116.   grobmap=(char *)malloc(sizeof(char)*(width/4)*height+1);
  117.   if (grobmap==NULL) {
  118.     fprintf(stderr,"GROB too big.  Exiting\n");
  119.     exit(4);
  120.   }
  121.   fgets(grobmap,(width/4)*height+1,fp_in);
  122.  
  123.   /*
  124.   **  Create memory space for a bitmap and clear that memory
  125.   **  to zero
  126.   */
  127.   bmap=(unsigned char *)malloc(sizeof(char)*width*(height/8));
  128.   if (bmap==NULL) {
  129.     fprintf(stderr,"GROB too big.  Exiting\n");
  130.     exit(4);
  131.   }
  132.   for(i=0;i<width*(height/8);i++)
  133.     bmap[i]=0;
  134.  
  135.   /*
  136.   **  Translate the grob string to a bitmap where each byte
  137.   **  represents 8 rows from 1 column.  This makes printing
  138.   **  upright images easier.
  139.   */
  140.   generate_bmap(grobmap,width,bmap);
  141.  
  142.   /*
  143.   **  Print out the bitmap
  144.   */
  145.   print_out(bmap,width,realwidth,height,fp_out);
  146.  
  147.   /*
  148.   **  Clean up and exit
  149.   */
  150.   free(grobmap);
  151.   free(bmap);
  152.   fclose(fp_in);
  153.   fclose(fp_out);
  154.   exit(0);
  155. }
  156.  
  157. int generate_bmap(grobmap,width,bmap)
  158. char *grobmap;
  159. int width;
  160. unsigned char *bmap;
  161. {
  162.   int i,j,bmaprow,bmapcol,bitrow;
  163.   char ch,*chptr;
  164.   unsigned char val,*bmap_indx,maptable0[16][8],maptable1[16][8],
  165.     maptable2[16][8],maptable3[16][8];
  166.  
  167.   /*
  168.   **  Initialize maptable#[hexnum][rownum] This array gives the
  169.   **  table which tells which columns (0-3) are 1 or 0 for each hex digit
  170.   **  and each row in the bitmap.
  171.   **  Note that the order of the bits is reversed since the HP-48 sends
  172.   **  the grobs this way, ie.  bit 0 is the leftmost bit and 3
  173.   **  the rightmost bit
  174.   */
  175.   for(i=1;i<16;i++)
  176.     for(j=0;j<8;j++) {
  177.       maptable0[i][j]=((i & 0x1) > 0) << j;
  178.       maptable1[i][j]=((i & 0x2) > 0) << j;
  179.       maptable2[i][j]=((i & 0x4) > 0) << j;
  180.       maptable3[i][j]=((i & 0x8) > 0) << j;
  181.     }
  182.  
  183.   /*
  184.   **  Scan the string, setting the appropriate bits in bmap.
  185.   **  Note that the MS bit of bmap is the top row.
  186.   */
  187.   bmaprow=0;
  188.   bitrow=7;
  189.   bmapcol=0;
  190.   chptr=grobmap;
  191.   for(i=0;i<strlen(grobmap); i++,bmapcol+=4,chptr++) {
  192.     /*
  193.     **  Calculate the value represented by the hex character
  194.     */
  195.     ch=*chptr;
  196.     if ((ch>='0') && (ch<='9'))
  197.       val=ch-'0';
  198.     else  {
  199.       ch=toupper(ch);
  200.       if ((ch>='A') && (ch<='F'))
  201. val=ch-'A'+10;
  202.       else val=0;
  203.     }
  204.     /*
  205.     **  Increment the current bit or column at the end of each row
  206.     */
  207.     if (bmapcol>=width) {
  208.       bmapcol-=width;
  209.       bitrow--;
  210.     }
  211.     if (bitrow<0)  {
  212.       bitrow=7;
  213.       bmaprow++;
  214.     }
  215.     /*
  216.     **  Skip a bit if there is a zero
  217.     */
  218.     if (val==0)
  219.       continue;
  220.     /*
  221.     **  bitwise-or each pixel column with the appropriate value
  222.     */
  223.     bmap_indx=bmap+bmapcol+width*bmaprow;
  224.     *bmap_indx++ |= maptable0[val][bitrow];
  225.     *bmap_indx++ |= maptable1[val][bitrow];
  226.     *bmap_indx++ |= maptable2[val][bitrow];
  227.     *bmap_indx   |= maptable3[val][bitrow];
  228.   }
  229. }
  230.  
  231. int print_out(bmap,width,realwidth,height,fp_out)
  232. unsigned char *bmap;
  233. int width,realwidth,height;
  234. FILE *fp_out;
  235. {
  236.   /*
  237.   **  Print out the bitmap.  This routine uses 8-bit single
  238.   **  density mode for epson printers.  On a 9-pin printer
  239.   **  the output is 60(H)x72(V) dpi. or 60(H)x60(V) dpi on
  240.   **  a 24-pin printer.  A normal size GROB will be pretty
  241.   **  small, but the calculator can produce larger ones
  242.   **  which will have better resolution
  243.   */
  244.  
  245.   int i,j;
  246.   /*
  247.   **  Set the line spacing
  248.   */
  249.   fprintf(fp_out,"%c%c%c",ESC,'3',24);
  250.  
  251.   for(j=0;j<(height/8);j++) {
  252.     /*
  253.     **  Print out one line of points
  254.     */
  255.     fprintf(fp_out,"%c%c%c%c",ESC,'K',realwidth%256,realwidth/256);
  256.     for(i=0;i<realwidth;i++)
  257.       fputc(*(bmap+j*width+i),fp_out);
  258.     /*
  259.     **  End of line - CR,LF
  260.     */
  261.     fprintf(fp_out,"%c%c",13,10);
  262.   }
  263.   /*
  264.   **  Restore the printer line spacing to 1/6 inch.
  265.   */
  266.   fprintf(fp_out,"%c%c",ESC,'2');
  267. }
  268.  
  269.